package com.primeton.eos.oss.model.controller;

import java.io.IOException;
import java.util.HashMap;
import java.util.List;
import java.util.Map;

import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;

import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.GetMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;

import com.alibaba.fastjson.JSONObject;
import com.eos.access.http.OnlineUserManager;
import com.eos.data.datacontext.UserObject;
import com.eos.spring.dao.CriteriaBuilder;
import com.primeton.eos.api.springboot.EOS8ApplicationContext;
import com.primeton.eos.oss.model.dao.AfcUserDao;
import com.primeton.eos.oss.model.newdataset.AfcUser;
import com.primeton.eos.oss.model.newdataset.CrecAccount;
import com.primeton.eos.oss.model.result.BusinessException;
import com.primeton.gocom.afcenter.api.oauth.ILoginService;

import cn.hutool.core.collection.CollectionUtil;
import cn.hutool.core.util.ObjectUtil;
import cn.hutool.http.HttpResponse;
import cn.hutool.http.HttpUtil;
import cn.hutool.json.JSONUtil;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
/**
 * 单点集成登陆
 * 
 * @author hudaheng
 *
 */
@Api(tags = "单点管理")
@RestController
@RequestMapping("/api/oss/singlePoint")
public class OssAuthController {

	private static final Logger log = LoggerFactory.getLogger(OssAuthController.class);

	public static final String AUTHORIZATION = "Authorization";

	public static final String BASEURL = EOS8ApplicationContext.INSTANCE.getProperty("oss.request.url");

	public static final String redirectUri = EOS8ApplicationContext.INSTANCE.getProperty("oss.redirect.api.uri");
	
	public static final String client_id = EOS8ApplicationContext.INSTANCE.getProperty("client_id");
	
	public static final String client_secret = EOS8ApplicationContext.INSTANCE.getProperty("client_secret");
	
	
	@Autowired
	ILoginService loginService;
	
	@Autowired
	AfcUserDao afcUserDao;

	@ApiOperation("单点重定向")
	@GetMapping("/singleOss")
	public void singleOss(HttpServletRequest request, HttpServletResponse response) throws IOException {
		String code = request.getParameter("code");
		log.info("oss come in.... code:" + code);
		if (StringUtils.isBlank(code)) {
			code = getAccessCode();
		}
		Map tokenMap = getAccessToken(code);
		Map userMap = getUsernameByToken(tokenMap);
		if (null == tokenMap) {
			log.info("userMap获取失败");
			throw new BusinessException("10001", "获取TOKEN无结果");
		}
        String loginName=(String) userMap.get("loginName");
        CriteriaBuilder cb = new CriteriaBuilder(AfcUser.QNAME);
        cb.and("code",loginName);
        List<AfcUser> afcUsers=afcUserDao.queryEntitiesByCriteria(cb.build());
        if(CollectionUtil.isEmpty(afcUsers)) {
        	log.info(loginName+"查无此用户，数据未同步");
			throw new BusinessException("10001", loginName+"数据未同步");
        }
		UserObject user = loginService.createUserObjectWithUserId(afcUsers.get(0).getId());
		OnlineUserManager.login(user);
		log.info("user信息" + JSONUtil.toJsonStr(user));
		String urlParam = AUTHORIZATION + "=" + user.getUniqueId();
		String url = EOS8ApplicationContext.INSTANCE.getProperty("oauth-config-afc-index-url") + "?" + urlParam;
		log.info("重定向url地址{}", url);
		response.sendRedirect(url);

	}

	/**
	 * 获取code
	 * 
	 * @return
	 */
	public static String getAccessCode() throws IOException {
		StringBuffer sb = new StringBuffer();
		sb.append(BASEURL).append("/idp/oauth2/authorize?redirect_uri=").append(redirectUri)
				.append("&state=123&client_id=").append(client_id).append("&response_type=code");
		log.info("获取code 地址：" + sb.toString());
		HttpResponse response = HttpUtil.createGet(sb.toString()).execute();
		if (!response.isOk()) {
			throw new IOException("Unexpected code " + response);
		}
		String body = response.body();
		log.info("获取code信息, 返回数据结果：" + body);
		if (!response.isOk()) {
			throw new IOException("Unexpected code " + response);
		}
		if (!ObjectUtil.isNotNull(body)) {
			throw new IOException("返回报文为空");
		}
		log.info("获取code信息, 返回数据结果：" + body);
		Map map = JSONUtil.toBean(body, Map.class);
		return (String) map.get("code");
	}
	
	
	/**
	 * 
	 * @param code
	 * @return map uid 用户唯一标识 access_token 令牌
	 * @throws IOException
	 */
	private static Map getAccessToken(String code) throws IOException {
		StringBuffer sb = new StringBuffer();
		String url = BASEURL + "/idp/oauth2/getToken";
		sb.append(url).append("?client_id=").append(client_id).append("&client_secret=").append(client_secret).append("&code=")
				.append(code).append("&grant_type=authorization_code");
		Map<String, String> headersMap = new HashMap();
		headersMap.put("Accept", "application/json");
		JSONObject jsonObject = new JSONObject();
		jsonObject.put("client_id", client_id);
		jsonObject.put("client_secret", client_secret);
		jsonObject.put("code", code);
		jsonObject.put("grant_type", "authorization_code");
		log.info("获取token参数" + JSONUtil.toJsonStr(jsonObject));
		HttpResponse response = HttpUtil.createPost(sb.toString()).addHeaders(headersMap)
				.body(JSONUtil.toJsonStr(jsonObject)).execute();
//		HttpResponse response = HttpUtil.createGet(sb.toString()).execute();
		if (!response.isOk()) {
			throw new IOException("Unexpected code " + response);
		}
		String body = response.body();
		log.info("code获取token,code:" + code + " 返回数据结果：" + body);
		if (!response.isOk()) {
			throw new IOException("Unexpected code " + response);
		}
		if (!ObjectUtil.isNotNull(body)) {
			throw new IOException("返回报文为空");
		}
		return JSONUtil.toBean(body, Map.class);
	}

	/**
	 * 获取个人信息
	 * 
	 * @param map
	 * @return
	 */
	private static Map getUsernameByToken(Map map) throws IOException {
		if (null == map) {
			throw new IOException("获取token信息失败");
		}
		String url = BASEURL;
		StringBuffer sb = new StringBuffer();
		sb.append(url).append("/idp/oauth2/getUserInfo?").append("client_id=").append(client_id).append("&access_token=")
				.append(map.get("access_token")).append("&uid=").append(map.get("uid"));
		HttpResponse response = HttpUtil.createGet(sb.toString()).execute();
		if (!response.isOk()) {
			throw new IOException("Unexpected code " + response);
		}
		String body = response.body();
		log.info("获取个人信息，返回数据结果：" + body);
		if (!response.isOk()) {
			throw new IOException("Unexpected code " + response);
		}
		if (!ObjectUtil.isNotNull(body)) {
			throw new IOException("返回报文为空");
		}
		return JSONUtil.toBean(body, Map.class);
	}

	private Map headerMap() {
		Map<String, String> headerMap = new HashMap();
		headerMap.put("Accept", "application/json");
		headerMap.put("Content-Type", "application/json");
		return headerMap;
	}
}
